package com.example.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.example.utils.constant.AirwallexConstant;
import com.example.utils.dto.PaymentCreateParamDTO;
import com.example.utils.dto.PaymentCreateParamDTO.AddressOfBeneficiary;
import com.example.utils.dto.PaymentCreateParamDTO.Bank_details;
import com.example.utils.dto.PaymentCreateParamDTO.Beneficiary;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.util.JsonUtils;

/**
 * @Description: 空中云汇工具类
 * @Auther: Swain
 * @Date: 2021/4/9 11:00
 * @Version 1.0.0
 */
@Data
public class AirwallexUtils {


    public static void main(String[] args) {
        PaymentCreateParamDTO paymentCreateParamDTO = new PaymentCreateParamDTO();
        Beneficiary beneficiary = new Beneficiary();
        AddressOfBeneficiary addressOfBeneficiary = new AddressOfBeneficiary();
        // 收款人邮编
        addressOfBeneficiary.setPostcode(getPostCode());
        // 收款人国家标准代码
        addressOfBeneficiary.setCountry_code("JP");
        // 收款人居住地
        addressOfBeneficiary.setCity("2-1-6 Uchisaiwaicho, Chiyoda-ku, Tokyo, Japan");
        addressOfBeneficiary.setState("2-1-6 Uchisaiwaicho, Chiyoda-ku, Tokyo, Japan");
        addressOfBeneficiary.setStreet_address("2-1-6 Uchisaiwaicho, Chiyoda-ku, Tokyo, Japan");
        beneficiary.setAddress(addressOfBeneficiary);
        Bank_details bank_details = new Bank_details();
        // 收款币种
        bank_details.setAccount_currency("JPY");
        // 收款账户名
        bank_details.setAccount_name("ASABA MEGUMI");
        // 收款账户号码
        bank_details.setAccount_number("0016074220");
        // 收款银行国家标准代码
        bank_details.setBank_country_code("JP");
        // 收款银行iban
        bank_details.setIban("12333");
        // 收款银行名称
        bank_details.setBank_name("SONY BANK INC.");
        // 收款swift_code
        bank_details.setSwift_code("SNYBJPJT");
        beneficiary.setBank_details(bank_details);
        beneficiary.setEntity_type("PERSONAL");
        // 收款人帐户名
        beneficiary.setFirst_name(bank_details.getAccount_name());
        beneficiary.setLast_name(bank_details.getAccount_name());
        paymentCreateParamDTO.setBeneficiary(beneficiary);
        // 付款金额
        paymentCreateParamDTO.setPayment_amount("15000");
        // 付款币种
        paymentCreateParamDTO.setPayment_currency("JPY");
        // 付款方式
        paymentCreateParamDTO.setPayment_method("SWIFT");
        // 付款理由
        paymentCreateParamDTO.setReason("wages_salary");
        // 付款便签
        paymentCreateParamDTO.setReference("salary for ASABA MEGUMI");
        // 教师薪酬支付平台流水唯一id
        String salaryRequestId = getSalaryRequestId("91982-0003");
        if (StringUtils.isBlank(salaryRequestId)) {
            System.out.println("教师薪酬支付平台流水唯一id生成异常");
        }
        paymentCreateParamDTO.setRequest_id(salaryRequestId);
        // 付款货币来源币种
        paymentCreateParamDTO.setSource_currency("CNY");
        // Swfit手续费付款方式
        paymentCreateParamDTO.setSwift_charge_option("PAYER");
        // 手续费付款方式
        paymentCreateParamDTO.setFee_paid_by("PAYER");
        /**
         * 创建支付
         */
//        System.out.println(paymentCreateTest(paymentCreateParamDTO));

        checkSuccessPaymentById("d5af3a37-f1e8-4f00-bbfd-02bc762271c8fc");

        getMarketfxQuoteOfAmount("USD","990.11");
    }

    /**
     * @param str
     * @return java.lang.String
     * @Description 获取新的教师薪酬流水唯一id(针对支付平台而言)
     * @Author swain
     * @Date 2021/4/16
     */
    public static String getSalaryRequestId(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        int index = str.lastIndexOf("-");
        if (index == -1) {
            return str + "-0000";
        } else {
            int value = Integer.parseInt(str.substring(index + 1));
            if (value < 0 || value >= 9999) {
                return null;
            }
            return str.substring(0, index + 1) + new DecimalFormat("0000").format(++value);
        }
    }

    /**
     * @return java.lang.String
     * @Description 获取随机邮编
     * @Author swain
     * @Date 2021/4/16
     */
    public static String getPostCode() {
        return String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
    }

    /**
     * @return java.lang.String
     * @Description 获取accessToken
     * @Author swain
     * @Date 2021/4/13
     */
    public static String getAccessTokenTest() {
        try {
            HttpResponse<HashMap> response = Unirest
                .post(AirwallexConstant.ACCESS_TOKEN_API)
                .header("Content-Type", "application/json;charset=utf-8")
                .header("x-api-key", AirwallexConstant.X_API_KEY)
                .header("x-client-id", AirwallexConstant.X_CLIENT_ID)
                .body("{}").asObject(HashMap.class);
            String accessToken = response.getBody().get("token").toString();

            if (response.getStatus() == 201) {
                return response.getBody().get("token").toString();
            } else {
                throw new Exception("获取accessToken失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param paymentCreateParamDTO 参数
     * @return java.lang.String
     * @Description 创建支付
     * @Author swain
     * @Date 2021/4/13
     */
    public static String paymentCreateTest(PaymentCreateParamDTO paymentCreateParamDTO) {
        try {
            System.out.println("paymentCreateTest:paymentCreateParamDTO:{}" +
                JSONObject
                    .toJSONString(paymentCreateParamDTO, SerializerFeature.WriteMapNullValue));

            HttpResponse<HashMap> response = Unirest
                .post(AirwallexConstant.PAYMENT_CREATE_API)
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + getAccessTokenTest())
                .body(JSONObject
                    .toJSONString(paymentCreateParamDTO, SerializerFeature.WriteMapNullValue))
                .asObject(HashMap.class);
            if (response.getStatus() == 201 && response.getBody().get("status").toString()
                .equals("NEW")) {
                return response.getBody().get("payment_id").toString();
            } else if (response.getStatus() == 400 && response.getBody().get("code").toString()
                .equals("invalid_argument")) {
                throw new Exception(
                    "教师薪酬id：" + paymentCreateParamDTO.getRequest_id() + "，字段错误：" + response
                        .getBody().get("source").toString() + "，错误描述：" + response.getBody()
                        .get("message").toString());
            } else {
                throw new Exception(
                    "教师薪酬id：" + paymentCreateParamDTO.getRequest_id() + "，未知错误：{}" + JSON
                        .toJSONString(response));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param paymentId 支付单id
     * @return java.lang.String
     * @Description 通过 paymentId 查询支付单
     * @Author swain
     * @Date 2021/4/13
     */
    public static Boolean checkSuccessPaymentById(String paymentId) {
        try {
            System.out.println("checkSuccessPaymentById:PaymentId:{}" + paymentId);

            HttpResponse<HashMap> response = Unirest
                .get(AirwallexConstant.PAYMENT_GETBYID_API + paymentId)
                .header("Authorization", "Bearer " + getAccessTokenTest())
                .asObject(HashMap.class);

            if (response.getStatusText().equals("OK")) {
                return !response.getBody().get("status").toString().equals("FAILED");
            } else {
                throw new Exception("教师薪酬 确认是否支付成功 错误：" + JSON.toJSONString(response));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String getMarketfxQuoteOfAmount(String buyCurrency, String amountOfCNY) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            HttpResponse<HashMap> response = Unirest
                .get(AirwallexConstant.MARKETFX_QUOTE_API
                    + "?buy_currency=" + buyCurrency
                    + "&conversion_date=" + simpleDateFormat.format(new Date())
                    + "&sell_amount=" + amountOfCNY
                    + "&sell_currency=CNY")
                .header("Authorization", "Bearer " + getAccessTokenTest())
                .asObject(HashMap.class);
            if ( response.getStatusText().equals("OK")) {
                return response.getBody().get("buy_amount").toString();
            } else {
                throw new Exception(
                    "转换当前汇率下 人民币金额对应的其他外币金额 buyCurrency:" + buyCurrency + ",amountOfCNY:"
                        + amountOfCNY + "，未知错误：{}" + JSON
                        .toJSONString(response));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
